﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace XinLife.Core.Helper
{
    /// <summary>
    /// JWTToken生成类
    /// </summary>
    public class JwtToken
    {
        //   /// <summary>
        /// 获取基于JWT的Token
        /// </summary>
        /// <param name="claims">需要在登陆的时候配置</param>
        /// <param name="jwtOption">在startup中定义的参数</param>
        /// <returns></returns>
        public static dynamic BuildJwtToken(Claim[] claims, JwtOption jwtOption)
        {
            var now = DateTime.Now;
            var keyByteArray = Encoding.UTF8.GetBytes(jwtOption.Secret);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 实例化JwtSecurityToken
            var jwt = new JwtSecurityToken(
                issuer: jwtOption.Issuer,
                audience: jwtOption.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(TimeSpan.FromMinutes(jwtOption.Expiration)),
                signingCredentials: signingCredentials
            );
            // 生成 Token
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            //打包返回前台
            var responseJson = new
            {
                success = true,
                token = encodedJwt,
                expires_in = jwtOption.Expiration,
                token_type = "Bearer"
            };
            return responseJson;
        }
    }

    /// <summary>
    /// JsonWebToken配置模型。
    /// </summary>
    public class JwtOption
    {
        /// <summary>
        /// 签发者。
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 收发者。
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 密钥。
        /// </summary>
        public string Secret { get; set; }

        /// <summary>
        /// Token有效期（单位：分钟）。
        /// </summary>
        public int Expiration { get; set; }
    }
}
